/*
 * Copyright 2012 ron-ang-code Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ron.ang.code.util;

/*
 * This code requires the JSON-Java library
 * http://www.json.org/java/
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

/**
 * 
 * @author Ronillo Ang
 */
public class FoursquareVenues {

	private static final String VENUES_SEARCH_API_URL = "https://api.foursquare.com/v2/venues/search?";

	private String clientId;
	private String clientSecret;

	public FoursquareVenues(String clientId, String clientSecret) {
		this.clientId = clientId;
		this.clientSecret = clientSecret;
	}

	public List<Venue> listNearby(double latitude, double longitude,
			String provider) throws IOException, JSONException {
		List<Venue> venueList = new ArrayList<Venue>();
		URL url = createVenuesSearchRequestUrl(latitude, longitude);

		HttpURLConnection urlConnection = (HttpURLConnection) url
				.openConnection();

		urlConnection.setRequestMethod("GET");
		urlConnection.setDoInput(true);
		urlConnection.connect();

		String response = streamToString(urlConnection.getInputStream());
		JSONObject jsonObj = (JSONObject) new JSONTokener(response).nextValue();
		JSONArray venues = (JSONArray) jsonObj.getJSONObject("response")
				.getJSONArray("venues");

		for (int j = 0; j < venues.length(); j++) {
			JSONObject item = (JSONObject) venues.get(j);

			Venue venue = new Venue();

			if (!item.isNull("name")) {
				venue.setName(item.getString("name"));
			}

			if (!item.isNull("location")) {
				JSONObject location = (JSONObject) item
						.getJSONObject("location");

				Location loc = new Location();

				loc.setProvider(provider);
				loc.setLatitude(Double.valueOf(location.getString("lat")));
				loc.setLongitude(Double.valueOf(location.getString("lng")));

				venue.setLocation(loc);

				if (!location.isNull("address")) {
					venue.setAddress(location.getString("address"));
				}
			}

			venueList.add(venue);
		}

		return venueList;
	}

	private URL createVenuesSearchRequestUrl(double latitude, double longitude)
			throws MalformedURLException {
		String ll = String.valueOf(latitude) + "," + String.valueOf(longitude);
		StringBuilder apiUrl = new StringBuilder(VENUES_SEARCH_API_URL);
		DateFormat df = new SimpleDateFormat("yyyyMMdd");

		apiUrl.append("ll=");
		apiUrl.append(ll);
		apiUrl.append("&sw=");
		apiUrl.append(ll);
		apiUrl.append("&radius=2000");
		apiUrl.append("&limit=50");
		apiUrl.append("&client_id=");
		apiUrl.append(clientId);
		apiUrl.append("&client_secret=");
		apiUrl.append(clientSecret);
		apiUrl.append("&v=");
		apiUrl.append(df.format(new Date()));

		URL url = new URL(apiUrl.toString());
		return url;
	}

	private String streamToString(InputStream is) throws IOException {
		String str = "";

		if (is != null) {
			StringBuilder sb = new StringBuilder();
			BufferedReader reader = new BufferedReader(
					new InputStreamReader(is));

			String line;
			while ((line = reader.readLine()) != null) {
				sb.append(line);
			}

			reader.close();
			str = sb.toString();
		}

		return str;
	}
}
